import numpy as np
import time


# 计算二维数组的平均值和标准差
def calculate_stats(array):
    mean = np.mean(array)
    std_dev = np.std(array)
    return mean, std_dev


def Open_Frame_IRV(inpath, frame, width, hight):
    f = open(inpath, "rb")  # rb：也即 binary mode，read()操作返回的是bytes
    # frame  = 10   #irv：32*1024 视频的头，(640*480*2+1024) 一帧的长度
    f.seek(32 * 1024 + (frame - 1) * (hight * width * 2 + 1024), 0)  # 第一个代表需要移动偏移的字节数,0 代表从文件开头开始算起
    ccc = f.read(hight * width * 2)  # python在读取文件的时候是根据光标位置来读取的。读一行以后光标位置到了下一行。再来个read又到了下一行。
    img = np.frombuffer(ccc,
                        dtype='uint16')  # read的数值以bytes的类型保存，通过np.frombuffer方法还原成类型为uint16的ndarray，这种方式还原出来的ndarray
    # 是只读的。
    img = img.reshape((hight, width))
    # img=img[:-2,:-2] #去边缘黑边
    # img = np.squeeze(img)
    f.close()
    return img


# 读取视频总帧数
def Read_TotalFrame_IRV(inpath, w, h):
    f = open(inpath, "rb")  # rb：也即 binary mode，read()操作返回的是bytes
    f.seek(0, 2)
    size = f.tell()
    Total_num = int((size - 32 * 1024) / (w * h * 2 + 1024)) - 1
    return Total_num


# 读取IRV并返回视频矩阵以及视频的平均值列表
def readIRV(irvpath):
    # 创建列表存储对应帧数视频图像
    # 求视频的总帧数
    w = 640
    h = 480
    Total_num = Read_TotalFrame_IRV(irvpath, w, h)
    print("总帧数:", Total_num)
    lists_gray = []
    mean_list = []
    for frame in range(1, Total_num + 1):
        img = Open_Frame_IRV(irvpath, frame, w, h)  # 读取红外AD值
        # 为列表赋值
        lists_gray.append(img)
        mean_list.append(np.mean(img))
    # lists_gray
    # 把lists_gray转换成np.array类型方便后续裁切 (存储的是整个视频的AD值数据)
    array_gray = np.array(lists_gray)
    return array_gray, mean_list


# r"E:\infraVideos\20240419\3mm7s50%.IRV" 坏点：[[0, 0], [0, 2], [0, 3], [0, 4], [0, 5], [0, 6], [0, 7], [0, 8], [0, 9],
# [0, 12], [0, 13]]
# r"E:\infraVideos\20240419\crossDefect25%.IRV" 坏点：[[0, 0], [0, 2], [0, 3], [0, 4], [0, 5], [0, 6],
# [0, 7], [0, 8], [0, 9],[0, 12], [0, 13]]
# r"E:\infraVideos\20240419\crossDefect100%.IRV" 坏点：[[0, 0], [0, 2], [0, 3], [0, 4], [0, 5], [0, 6],
# [0, 7], [0, 8], [0, 9],[0, 12], [0, 13]]
# r"E:\infraVideos\20240419\noDefect.IRV" 坏点：[[0, 0], [0, 2], [0, 3], [0, 4], [0, 5], [0, 6],
# [0, 7], [0, 8], [0, 9],[0, 12], [0, 13]]
# r"E:\infraVideos\20240424\thinNoTexture.IRV" 坏点：[[0, 0], [0, 2], [0, 3], [0, 4], [0, 5], [0, 6],
# [0, 7], [0, 8], [0, 9],[0, 12], [0, 13]]
# r"E:\infraVideos\2024-0307\002.IRV" 坏点：[[0, 0], [0, 2], [0, 3], [0, 4], [0, 5], [0, 6],
# [0, 7], [0, 8], [0, 9],[0, 12], [0, 13]]
# r"E:\infraVideos\2023.09.18\20230918214038.IRV" 坏点：[[0, 0], [0, 2], [0, 3], [0, 4], [0, 5], [0, 6],
# [0, 7], [0, 8], [0, 9],[0, 12], [0, 13]]

#制冷热像仪
# r"E:\infraVideos\2024.01.31\cold3.IRV" 坏点：[]
# r"E:\infraVideos\2024.01.31\cold2.IRV" 坏点：[]
if __name__ == "__main__":

    irvpath = r"E:\infraVideos\2024.01.31\cold1.IRV"

    # 创建列表存储坏点
    badPoints = []

    # 读取整个视频的AD值以及计算平均参数
    array_ad, mean_list = readIRV(irvpath)
    print(f"全图平均ad为：{mean_list}")
    mean_mean, std_mean = calculate_stats(mean_list)
    print(f"全图平均ad的平均值：{mean_mean},标准差：{std_mean}")
    Max_mean = max(mean_list)
    Min_mean = min(mean_list)
    range_mean = Max_mean - Min_mean
    print(f"全图平均ad的最大值：{Max_mean},最小值：{Min_mean}, 数据范围：{range_mean}")

    # 遍历每个点
    for i in range(480):
        for j in range(640):
            list_ad = array_ad[:, i, j]
            # print(f"{i}行{j}列的ad值为：{list_ad}")
            mean, std = calculate_stats(list_ad)
            # print(f"{i}行{j}列的平均值：{mean},标准差：{std}")
            Max = max(list_ad)
            Min = min(list_ad)
            range_each = Max - Min
            # print(f"{i}行{j}列的最大值：{Max},最小值：{Min}, 数据范围：{range_each}")
            # 坏点加入坏点列表
            if (range_each > range_mean * 5 or range_each < 10  # 数据范围
                    or std < 10  # 标准差
                    or mean < mean_mean - 5000 or mean > mean_mean + 5000):  # 平均值
                badPoints.append([i, j])
                print(f"坐标：x = {i} y = {j} 的平均值值为{mean}, 标准差为{std}, 数据范围：{range_each}, 从{Min} ~ {Max}")
    print("坏点个数：", len(badPoints))
    print("坏点坐标：", badPoints)
